<?php
declare(strict_types=1);

namespace app\api\controller;

use app\api\service\ChannelOrder as ChannelOrderService;
use app\common\controller\Api;
use app\common\model\delivery\ChannelOrder;
use app\common\model\delivery\CouponList;
use app\common\model\delivery\Customer;
use app\common\model\delivery\Driver as DriverModel;
use app\common\model\delivery\DriverPosition;
use app\common\model\delivery\PayLog;
use think\annotation\route\Get;
use think\annotation\route\Group;
use think\annotation\route\Post;
use think\facade\Db;

function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){
    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI = 3.1415926;
    $radLat1 = $latitude1 * $PI / 180.0;
    $radLat2 = $latitude2 * $PI / 180.0;
    $radLng1 = $longitude1 * $PI / 180.0;
    $radLng2 = $longitude2 * $PI /180.0;
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
    $distance = $distance * $EARTH_RADIUS * 1000;
    if($unit==2){
        $distance = $distance / 1000;
    }
    return round($distance, $decimal);
}

#[Group("driver")]
class Driver extends Api
{

    protected $drivers=[];

    protected $customer=[];

    protected function _initialize()
    {
        parent::_initialize();
        $drivers=DriverModel::where(['user_id'=>$this->auth->id,'status'=>'normal'])->select();
        if(count($drivers)==0){
            $this->error('你没有权限！');
        }
        $this->drivers=$drivers;
    }

    #[Get('total')]
    public function total()
    {
        $list=ChannelOrder::where(function ($query){
            $delivery_day=date('Y-m-d',time());
            $query->where(['is_cancel'=>0,'delivery_day'=>$delivery_day]);
            $girdids= DriverModel::getGirdIds($this->drivers,$this->auth->id);
            $query->whereIn('gird_id',$girdids);
            $query->whereRaw("number>refuse_number and (is_pay=1 or (pay_type='delivery' and is_pay=0))");
        })
       ->with(['goods','spec'])
       ->group('goods_id,spec_id')
       ->field('goods_id,spec_id,sum(number-refuse_number) as total_number,sum(total_money) as total_money')
       ->select();
        $this->success('',$list);
    }

    #[Get('order')]
    public function order()
    {
        $now=time();
        $type=$this->request->get('type');
        $longitude=$this->request->get('longitude');
        $latitude=$this->request->get('latitude');
        $delivery_day='';
        if($type=='today'){
            $delivery_day=date('Y-m-d',$now);
            DriverPosition::add($this->drivers,$latitude,$longitude);
        }
        if($type=='yesterday'){
            $delivery_day=date('Y-m-d',$now-24*3600);
        }
        if($type=='tomorrow'){
            $delivery_day=date('Y-m-d',$now+24*3600);
        }
        $list=ChannelOrder::where(function ($query) use ($type,$now,$longitude,$latitude,$delivery_day){
            $query->where(['is_cancel'=>0,'delivery_day'=>$delivery_day]);
            $girdids= DriverModel::getGirdIds($this->drivers,$this->auth->id);
            $query->whereIn('channel_order.gird_id',$girdids);
            $query->whereRaw("number>refuse_number and (is_pay=1 or (pay_type='delivery' and is_pay=0))");
        })
        ->with(['goods','spec','address'])
        ->withJoin(['customer'],'inner')
        ->order('channel_order.id desc')
        ->field('channel_order.id,channel_order.channel_id,customer_id,goods_id,order_no,number,total_money,is_pay,refuse_number,receive_time,remark')
        ->select();
        $newList=[];
        foreach ($list as $newItem) {
            $customer_id=$newItem->customer_id;
            $h_latitude=$newItem->customer->latitude;
            $h_longitude=$newItem->customer->longitude;;
            $distance=getDistance($longitude,$latitude,$h_longitude,$h_latitude,1);
            if(!isset($newList[$customer_id])){
                $title='';
                if($newItem['customer']['customer_type']=='family'){
                    $title=$newItem['customer']['address'];
                }
                if($newItem['customer']['customer_type']=='company'){
                    $title=$newItem['customer']['name'];
                }
                $newList[$customer_id]=[
                    'position'=>[
                        'title'=>$title,
                        'latitude'=>$newItem['customer']['latitude'],
                        'longitude'=>$newItem['customer']['longitude'],
                    ],
                    'type'=>'orders',
                    'list'=>[],
                    'distance'=>$distance
                ];
            }
            array_push($newList[$customer_id]['list'],$newItem);
        }
        if($type=='today'){
            $wxdlist=$this->getWeixiadan($newList);
            foreach ($wxdlist as $value){
                $distance=getDistance($longitude,$latitude,$value['longitude'],$value['latitude'],1);
                $title='';
                if($value['customer_type']=='family'){
                    $title=$value['address'];
                }
                if($value['customer_type']=='company'){
                    $title=$value['name'];
                }
                $newList[$value['customer_id']]=[
                    'position'=>[
                        'title'=>$title,
                        'latitude'=>$value['latitude'],
                        'longitude'=>$value['longitude'],
                    ],
                    'customer'=>[
                        'id'=>$value['customer_id'],
                        'channel_id'=>$value['channel_id'],
                        'name'=>$value['name'],
                        'latitude'=>$value['latitude'],
                        'longitude'=>$value['longitude'],
                        'contact'=>$value['contact'],
                        'mobile'=>$value['mobile'],
                        'address'=>$value['address'],
                        'settle_type'=>$value['settle_type'],
                        'customer_type'=>$value['customer_type']
                    ],
                    'type'=>'weixiadan',
                    'distance'=>$distance,
                    'delivery_day'=>$value['delivery_day']
                ];
            }
        }
        $sort=[];
        foreach ($newList as $hair_id=>$value){
            $sort[$hair_id]=$value['distance'];
        }
        asort($sort);
        $r=[];
        foreach ($sort as $hair_id=>$value){
            $r[]=$newList[$hair_id];
        }
        $this->success('',$r);
    }

    private function getWeixiadan($newList)
    {
        $hst='';
        if(count($newList)>0){
            $customerids=array_keys($newList);
            $customerids=implode(',',$customerids);
            $hst="and customer.id not in ({$customerids})";
        }
        $girdids= DriverModel::getGirdIds($this->drivers,$this->auth->id);
        if(count($girdids)>0){
            $fst="and customer.gird_id in (".implode(',',$girdids).")";
        }else{
            return [];
        }
        $prefix=getDbPrefix();
        $sql="
            SELECT t1.*,t2.delivery_day FROM
            (
            SELECT
            customer.channel_id as channel_id,
            customer.id as customer_id,
            customer.name,
            customer.contact,
            customer.mobile,
            customer.address,
            customer.latitude,
            customer.longitude,
            customer.settle_type,
            customer.customer_type
            FROM
            {$prefix}customer customer
            left join {$prefix}channel channel on channel.id=customer.channel_id
            WHERE
            customer.deletetime is null
            and customer.status='normal'
            {$hst}
            {$fst}
            limit 30
            )t1 
            LEFT JOIN (select customer_id,delivery_day from {$prefix}channel_order where id in (select max(id) as order_id from {$prefix}channel_order GROUP BY customer_id)) t2 ON t2.customer_id=t1.customer_id
        ";
        $list=Db::query($sql);
        return $list;
    }

    #[Post('pay')]
    public function pay($id)
    {
        /* @var ChannelOrder $order*/
        $order=ChannelOrder::find($id);
        if($order->is_pay){
            $this->error('该订单已经支付');
        }
        if($order->pay_type!=ChannelOrder::PAY_TYPE('货到付款')){
            $this->error('该订单不是货到付款');
        }
        $log=new PayLog();
        $log->save([
            'user_id'=>$this->auth->id,
            'type'=>PayLog::TYPE('支付订单'),
            'pay_price'=>$order->total_money,
            'out_trade_no'=>$order['order_no'],
            'pay_status'=>1,
            'pay_time'=>date('Y-m-d H:i:s',time())
        ]);
        $order->is_pay=1;
        $order->pay_id=$log->id;
        $order->save();
        $this->success('操作成功');
    }

    #[Post('receive')]
    public function receive($id)
    {
        $order=ChannelOrder::with(['customer','goods'])->find($id);
        if($order->receive_time){
            $this->error('该订单已经送达');
        }
        foreach ($this->drivers as $driver){
            if($order->channel_id==$driver->channel_id){
                $order->driver_id=$driver->id;
                break;
            }
        }
        if(!$order->driver_id){
            $this->error('没有操作权限');
        }
        Db::startTrans();
        try{
            $order->receive();
            Db::commit();
        }catch (\Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('操作成功');
    }

    #[Get('getCustomer')]
    public function getCustomer($customer_id)
    {
        $customer=Customer::with(['goods','channel'])->find($customer_id);
        $goods=Customer::parseGoods($customer->goods,$customer->channel);
        foreach ($goods as &$value){
            $value['name']=$value['goods_name'].'-'.$value['spec_name'];
        }
        $customer->goods=$goods;
        $this->success('',$customer);
    }

    #[Get('store')]
    public function store()
    {
        $page=$this->request->get('page/d',1);
        $offest=($page-1)*15;
        $list=Customer::withJoin(['area','channel'],'left')->where(function ($query){
            $keywords=$this->request->get('keywords');
            $girdids= DriverModel::getGirdIds($this->drivers,$this->auth->id);
            $query->where('customer.gird_id','in',$girdids);
            if($keywords){
                $query->where('customer.name','like',"%{$keywords}%");
            }
        })->limit($offest,15)->order('customer.id desc')->select();
        $this->success('',$list);
    }

    #[Post('updatecover')]
    public function updatecover()
    {
        $id=$this->request->post('id/d');
        $cover_url=$this->request->post('url');
        $customer=Customer::find($id);
        $customer->cover_url=$cover_url;
        $customer->save();
        $this->success('操作成功');
    }

    #[Post('createOrder')]
    public function createOrder()
    {
        $data=$this->request->post();
        $data['order_type']= ChannelOrder::ORDER_TYPE('代客下单');
        foreach ($this->drivers as $driver){
            if($data['channel_id']==$driver->channel_id){
                $data['bill_driver_id']= $driver->id;
                break;
            }
        }
        if(!isset($data['bill_driver_id'])){
            $this->error('没有操作权限');
        }
        try {
            ChannelOrderService::newInstance($data)->createOrder();
        }catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
        $this->success('下单成功');
    }

    #[Post('refuse')]
    public function refuse()
    {
        $postdata=$this->request->post();
        $order=ChannelOrder::find($postdata['id']);
        $driver='';
        foreach ($this->drivers as $value){
            if($order->channel_id==$value->channel_id){
                $driver=$value;
                break;
            }
        }
        if(!$driver){
            $this->error('没有操作权限');
        }
        try{
            $order->cancelSuccess($postdata['refuse_number'],'司机'.$driver->realname.'取消订单，'.$postdata['refuse_remark']);
        }catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
        $this->success('操作成功');
    }

    #[Get('getCustomerInfo')]
    public function getCustomerInfo()
    {
        $customer_id=$this->request->get('customer_id');
        $customer=Customer::with(['goods','channel','address'])->where("id",$customer_id)->find();
        if($customer['customer_type']=='family'){
            $customer['name']=$customer['address'];
        }
        $customer['goods']=Customer::parseGoods($customer['goods'],$customer['channel']);
        $this->success('',$customer);
    }

    #[Get('coupon')]
    public function coupon()
    {
        $customer_id=$this->request->get('customer_id');
        $where=[];
        $where[]=['coupon_list.customer_id','=',$customer_id];
        $where[]=['coupon_list.expire_time','>',time()];
        $where[]=['coupon.deletetime','=',null];
        $list=CouponList::where($where)->whereRaw('coupon_list.total>coupon_list.take')->withJoin(['coupon'],'inner')->select();
        $r=[];
        foreach($list as $value) {
            $desc = '';
            if ($value['coupon']['type'] == 'goods') {
                $desc = '余额：' . ($value['total'] - $value['take']);
            }
            if ($value['coupon']['type'] == 'card') {
                $desc = '余额：￥' . $value['balance'];
            }
            if ($value['coupon']['type'] == 'cash') {
                $desc = '抵扣：￥' . $value['coupon']['cash'];
            }
            if ($value['coupon']['type'] == 'discount') {
                $desc = $value['coupon']['discount'] . '折';
            }
            if ($value['coupon']['type'] == 'full_minus') {
                $full_minus = json_decode($value['coupon']['full_minus'], true);
                foreach ($full_minus as $man => $jian) {
                    $man = floatval($man);
                    $jian = floatval($jian);
                    $desc = '满' . $man . '减' . $jian . '等优惠';
                    break;
                }
            }
            $r[] = [
                'id' => $value['id'],
                'goods_id'=>explode(',',$value['coupon']['goods_id']),
                'name' => $value['coupon']['title'],
                'desc' => $desc,
            ];
        }
        $this->success('',$r);
    }
}